﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Xml.Linq;

//-----------------------------------------------------------
// All Rights Reserved , Copyright (C) 2012,LNOne,Ltd .
//-----------------------------------------------------------
namespace LinqTutorial
{
    class Program
    {
        static void Main(string[] args)
        {
            LinqSelect();
            LingWhere();
            //http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

            HelloLINQ();
            LinqToXML();
            LinqtoXMLQuery();
            LinqToObject();
            //LinqToSQLSelect();
            //LinqToSQLDelete();
            //LinqToSQLInsert();
            //LinqToSQLUpdate();

            //Linq as Extension Method
            var query = System.Diagnostics.Process.GetProcesses().Where(p => p.Threads.Count > 10).OrderBy(p => p.ProcessName)
                .ThenBy(p => p.Id)
                .Select(p => new
                {
                    Name = p.ProcessName,
                    ID = p.Id,
                    Threads = p.Threads.Count
                }
                    );

            foreach (var p in query)
            {
                Console.WriteLine(p);
            }

            Console.Read();


            //Linq with 'SQL-like SYntax'
            var query2 = from p in Process.GetProcesses()
                         where p.Threads.Count > 10
                         orderby p.ProcessName, p.Id
                         select new
                         {
                             Name = p.ProcessName,
                             ID = p.Id,
                             Threads = p.Threads.Count
                         };


            foreach (var p in query2)
            {
                Console.WriteLine(p);
            }

            Console.Read();


            var rnd = new Random();

            var numbers = Enumerable.Range(0, 100).Select(n => rnd.Next(100));
            int sum = numbers.Sum();
            double avg2 = numbers.Average(n => Math.Sqrt(n));

                


        }

        /// <summary>
        /// Hello LINQ.
        /// </summary>
        private static void HelloLINQ()
        {
            //声明数组
            string[] greetings = { "hello world", "hello LINQ", "hello LN" };

            //查询以LINQ结束的元素
            var items = from s in greetings where s.EndsWith("LINQ") select s;

            foreach (var item in items)
            {
                Console.WriteLine(item);
            }
        }

        private static void LingWhere()
        {
            int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

            var lowNums =
                from n in numbers
                where n < 5
                select n;

            Console.WriteLine("Numbers < 5:");
            foreach (var x in lowNums)
            {
                Console.WriteLine(x);
            }

        }


        private static void LinqSelect()
        {
            int[] numbers = { 4, 5, 6, 3, 8, 1, 23, 13, 11 };
            var results = from num in numbers
                          select num+1;

            foreach (var item in results)
            {
                Console.WriteLine(item);
            }

            //This sample uses an indexed Select clause to determine if the value of ints in an array match their position in the array.
            var numInPlace = numbers.Select((num, index) => new { Num = num, InPlace = (num == index) });

            foreach (var item in numInPlace)
            {
                Console.WriteLine("{0}:{1}", item.Num, item.InPlace);
            }


            int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
            int[] numbersB = { 1, 3, 5, 7, 8 };

            var pairs =
                from a in numbersA
                from b in numbersB
                where a < b
                select new { a, b };

            Console.WriteLine("Pairs where a < b:");
            foreach (var pair in pairs)
            {
                Console.WriteLine("{0} is less than {1}", pair.a, pair.b);
            } 


        }


        /// <summary>
        /// Usage of classes under namespace System.xml.linq.
        /// </summary>
        private static void LinqToXML()
        {
            XElement tree = new XElement("Root", new XElement("ChildOne", 1), new XElement("ChildTwo", 2));
            Console.WriteLine(tree);

            tree.Element("ChildOne").AddAfterSelf(new XElement("ChildThree", 3));
            Console.WriteLine(tree);

            tree.Changing += new EventHandler<XObjectChangeEventArgs>(XMLChanging);
            tree.Changed += new EventHandler<XObjectChangeEventArgs>(XMLChanged);

            tree.Element("ChildOne").SetAttributeValue("Id", 1);


            tree.Save("linqtoXML.xml");

        }

        static void XMLChanging(object sender, XObjectChangeEventArgs e)
        {
            Console.WriteLine("ChangedValue:" + ((XAttribute)sender).ToString() + "ObjectChange:" + e.ObjectChange);
        }

        static void XMLChanged(object sender, XObjectChangeEventArgs e)
        {
            Console.WriteLine("ChangedValue:" + ((XAttribute)sender).ToString() + "ObjectChange:" + e.ObjectChange);
        }

        private static void LinqtoXMLQuery()
        {
            //Load from xml
            XElement element = XElement.Load("linqtoXML.xml");
            Console.WriteLine(element);

            //Load from string
            XElement books = XElement.Parse(
              @"<books>
                  <book>
                    <title>Pro LINQ: Language Integrated Query in C# 2008</title>
                    <author>Joe Rattz</author>
                  </book>
                  <book>
                    <title>Pro WF: Windows Workflow in .NET 3.0</title>
                    <author>Bruce Bukovics</author>
                  </book>
                  <book>
                    <title>Pro C# 2005 and the .NET 2.0 Platform, Third Edition</title>
                    <author>Andrew Troelsen</author>
                  </book>
                </books>");


            var titles =
              from book in books.Elements("book")
              where (string)book.Element("author") == "Joe Rattz"
              select book.Element("title");

            foreach (var title in titles)
            {
                Console.WriteLine(title.Value);
            }

        }



        /// <summary>
        /// Linq to Object
        /// </summary>
        private static void LinqToObject()
        {
            List<Person> persons = new List<Person>();
            persons.Add(new Person() { Name = "Zhang San", Age = 20 });
            persons.Add(new Person() { Name = "Li si", Age = 30 });

            var ps = persons.Where(p => p.Age > 25);

            foreach (var item in ps)
            {
                Console.WriteLine(item.ToString());
            }
        }


        /// <summary>
        /// Sort Array using Linq.
        /// </summary>
        private static void SortArray()
        {
            //排序
            int[] nums = new int[] { 123, 3, 34, 54, 23, 34 };

            nums = nums.OrderBy(n => n).ToArray();

            foreach (int num in nums)
                Console.WriteLine(num);
        }

        /// <summary>
        /// Linq to SQL.
        /// </summary>
        private static void LinqToSQLSelect()
        {
            LinqToSQLDataContext linqContext = new LinqToSQLDataContext();
            var users = linqContext.Users.Select(u => u).Where(u => u.Name.StartsWith("zhang"));
            foreach (var user in users)
            {
                Console.WriteLine(user.Name);
            }
        }

        private static void LinqToSQLInsert()
        {
            LinqToSQLDataContext linqContext = new LinqToSQLDataContext();
            User user = new User() { Name = "liu ning" };
            linqContext.Users.InsertOnSubmit(user);
            linqContext.SubmitChanges();

        }
        private static void LinqToSQLDelete()
        {
            LinqToSQLDataContext linqContext = new LinqToSQLDataContext();
            var users = linqContext.Users.Select(u => u).Where(u => u.Name.StartsWith("liu"));
            foreach (var user in users)
            {
                linqContext.Users.DeleteOnSubmit(user);
            }

            linqContext.SubmitChanges();
        }

        private static void LinqToSQLUpdate()
        {
            LinqToSQLDataContext linqContext = new LinqToSQLDataContext();
            User user = linqContext.Users.Single(u => u.Id == 1);

            user.Name = "zhang san" + DateTime.Now.ToString();


            linqContext.SubmitChanges();
        }
    }

    /// <summary>
    /// Entity Class Person.
    /// </summary>
    public class Person
    {
        public string Name { get; set; }

        public int Age { get; set; }

        public override string ToString()
        {
            return String.Format("Name:{0} \t\t Age:{1}", Name, Age);
        }

    }



}
